iT邦幫忙

2022 iThome 鐵人賽

DAY 5
0
Web 3

Smart-Contract Language: Move系列 第 14

Day 14 Advanced Topics: Generics

  • 分享至 

  • xImage
  •  

泛型可以讓 Move 在使用上更靈活,在其他語言亦是如此。

泛型是具體類型或其他屬性的抽象替代品。在 Move 中,泛型可以應用於 StructFunction

在結構中使用

// 在之前篇章有介紹過的 struct 
module Storage {
    struct Box {
        value: u64
    }
}

// 使用泛型的 struct
module Storage {
    struct Box<T> {
        value: T
    }
}

在函數中使用

struct Foo<T> has copy, drop { x: T }

在函數調用中使用

address 0x3 {
module M {
	struct Box<T> has drop {				
	      value: T
	}

	public fun create_box<T>(value: T): Box<T> {
	      Box<T> { value }
  }

    
  public fun value<T: copy>(box: &Box<T>): T {
        box.value
  }
}
}

// 在 main function 中使用
script {
		use 0x3::M;
    use 0x1::Debug;

    fun main() {

				// 使用 bool
        let bool_box = M::create_box<bool>(true);
        let box_value = M::value(&bool_box);

        assert(box_value, 0); // true

				// 使用 integer
		let u64_box = M::create_box<u64>(10000);
        let box_value_2 = M::value(&u64_box);

        assert(box_value2, 10000); // true
    }
}

我們通過向 struct 添加泛型,使 Box 可以使用任何類型創建,無論是 bool, u64, address, 甚至是另一個 box 和 另一個結構。

檢查能力的約束

在前幾篇中,我們介紹過能力,他們可以在泛型中檢查或約束

// 在 function 中
fun name<T: copy>() {} // 參數允許被複製
fun name<T: copy + drop>() {} // 參數可以 drop 掉
fun name<T: key + store + drop + copy>() {} // 擁有四項能力

// 在 Struct 中
struct name<T: copy + drop> { value: T } // T 有複製和 drop 能力
struct name<T: store> { value: T } // T 有儲存在全局儲存

加號 (+) 語法唯一用在這邊

約束系統

參數和 struct 分別可以搭配 type 能力

module Storage {

	// Box 可以被儲存
    struct Box<T: store> has key, store {
        content: T
    }
}

Move 的容器能力會自動受到其內容限制,
例如有一個具有複製,刪除和儲存的 Struct, 而內部結構只有 drop,則無法複製或儲存該容器,解決方法是,容器需要對內部類型有約束。

module Storage {
    // 沒有任何能力的 struct
    struct Error {}
    
	// Box 能力會被 T 能力影響, constents 將無任何能力
    struct Box<T> has copy, drop {
        contents: T
    }

    // 這樣只會產生沒有 copy 和 drop 能力的 contents
	// 如果 script 要使用時將會 error
    public fun create_box(): Box<Error> {
        Box { contents: Error {} }
    }
}

我們可以這樣宣告,讓 inner type 遵循 parent’s 能力

// T 擁有 parent's copy 和 drop 能力
struct Box<T: copy + drop> has copy, drop {
    contents: T
}

泛型中的多種類型

使用 <> 和逗號使用多個泛型

module Storage {

    struct Box<T> {
        value: T
    }

    struct Shelf<T1, T2> {
        box_1: Box<T1>,
        box_2: Box<T2>
    }

    public fun create_shelf<Type1, Type2>(
        box_1: Box<Type1>,
        box_2: Box<Type2>
    ): Shelf<Type1, Type2> {
        Shelf {
            box_1,
            box_2
        }
    }
}

未使用的類型參數

並非必須使用泛型中指定得每種類型

module Storage {

    struct Abroad {}
    struct Local {}

    struct Box<T, Destination> {
        value: T
    }
		
	// 使用泛型當作某些操作的約束,我們後面介紹資源概念時會再提到
    public fun create_box<T, Dest>(value: T): Box<T, Dest> {
        Box { value }
    }
}

script {
		use 0x4::Storage;

    fun main() {
        // value will be of type Storage::Box<bool>
        let _ = Storage::create_box<bool, Storage::Abroad>(true);
        let _ = Storage::create_box<u64, Storage::Abroad>(1000);

        let _ = Storage::create_box<u128, Storage::Local>(1000);
        let _ = Storage::create_box<address, Storage::Local>(0x1);

        // or even u64 destination!
        let _ = Storage::create_box<address, u64>(0x1);
    }
}

本篇介紹了大部分語言都有的泛型, Move 可以使用在 struct 和 function 中,同時搭配 type 能力來約束。讓我們 Move to Day 15


上一篇
Day 13 Advanced Topics: Ownership
下一篇
Day 15 Advanced Topics: Vector
系列文
Smart-Contract Language: Move30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言